/**
 *
 */
package com.ybkj.daijia.server.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.Pageable;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.page.impl.PageRequest;
import com.ybkj.daijia.server.event.model.DriverPowerOfflineEvent;
import com.ybkj.daijia.server.event.model.NoticeEvent;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mapper.DriverEnchashmentMapper;
import com.ybkj.daijia.server.mapper.DriverMapper;
import com.ybkj.daijia.server.mapper.DriverPaymentsRecordMapper;
import com.ybkj.daijia.server.mapper.NoticeMapper;
import com.ybkj.daijia.server.mapper.NoticeXDriverMapper;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverEnchashment;
import com.ybkj.daijia.server.model.DriverPaymentsRecord;
import com.ybkj.daijia.server.model.HelpPayRecord;
import com.ybkj.daijia.server.model.Notice;
import com.ybkj.daijia.server.model.NoticeXDriver;
import com.ybkj.daijia.server.service.DriverEnchashmentService;
import com.ybkj.daijia.server.service.DriverHelppayService;
import com.ybkj.daijia.serverUtils.SettingUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Shine
 *
 */
@Service
public class DefaultDriverEnchashmentService implements
    DriverEnchashmentService {

    @Autowired
    private DriverEnchashmentMapper driverEnchashmentMapper;

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private DriverPaymentsRecordMapper driverPaymentsRecordMapper;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private NoticeXDriverMapper noticeXDriverMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private DriverHelppayService helppayService;

    @Override
    public JSONObject statistics() {
        //驾驶员充值金额总数
        BigDecimal driverIncome = driverEnchashmentMapper.getDriverIncome();
        //乘客充值金额总数
        BigDecimal passengerIncome = driverEnchashmentMapper.getPassengerIncome();
        //充值总数
        BigDecimal income = driverIncome.add(passengerIncome).setScale(2);
        //已审核通过提现金额总数
        BigDecimal withdraw = driverEnchashmentMapper.getWithdraw().setScale(2);
        //当前未通过审核提现金额总数
        BigDecimal nonWithdraw = driverEnchashmentMapper.getCurrentWithdraw().setScale(2);
        //公司余额（充值-已审核通过提现）
        BigDecimal balance = income.subtract(withdraw).setScale(2);
        JSONObject json = new JSONObject();
        json.put("income", income);
        json.put("withdraw", withdraw);
        json.put("balance", balance);
        json.put("nonwithdraw", nonWithdraw);
        return json;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ybkj.shop.service.AdminService#queryAll()
     */
    @Override
    public Page<DriverEnchashment> queryByEmploy(Long employId, String param, Integer page, Integer limit) {

        Pageable pageable = new PageRequest(page, limit);

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        String likeParam = null;
        Long[] companyIds = null;

        if (null != principal) {
            if (!principal.isCompanyType()) {
                companyIds = new Long[1];
                companyIds[0] = principal.getCompanyId();
            }
        }

        if (StringUtils.isNotBlank(param)) {
            likeParam = "%" + param + "%";
        }

        List<DriverEnchashment> content = driverEnchashmentMapper.selectByPage(employId, likeParam, page * limit, limit, companyIds);
        long total = driverEnchashmentMapper.countByPage(employId, likeParam, companyIds);

        return new PageImpl<DriverEnchashment>(content, pageable, total);

    }

    @Override
    public List<DriverEnchashment> listByEmploy(Long employId, String param) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        String likeParam = null;
        Long[] companyIds = null;

        if (null != principal) {
            if (!principal.isCompanyType()) {
                companyIds = new Long[1];
                companyIds[0] = principal.getCompanyId();
            }
        }

        if (StringUtils.isNotBlank(param)) {
            likeParam = "%" + param + "%";
        }

        List<DriverEnchashment> content = driverEnchashmentMapper.selectBylist(
            employId, likeParam, companyIds);
        return content;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DriverEnchashment insertRecord(DriverEnchashment driverEnchashment) {

        driverEnchashmentMapper.insertRecord(driverEnchashment);

        return driverEnchashment;
    }

    @Override
    public DriverEnchashment findOne(Long id) {

        return driverEnchashmentMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(DriverEnchashment driverEnchashment) {

        driverEnchashmentMapper.deleteByPrimaryKey(driverEnchashment.getId());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(DriverEnchashment driverEnchashment) {

        return driverEnchashmentMapper.updateByPrimaryKey(driverEnchashment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyEnchashment(Driver driver, BigDecimal money, String bank,
        String cardNumber, String masterName, String type) {

        try {

            Company company = companyMapper.selectByPrimaryKey(driver.getCompanyId());

            DriverEnchashment driverEnchashment = new DriverEnchashment();
            driverEnchashment.setEmployId(driver.getId());
            driverEnchashment.setEmployPhone(driver.getPhone());
            driverEnchashment.setEmployRealName(driver.getRealname());
            driverEnchashment.setEmployUserName(driver.getUsername());
            driverEnchashment.setCompanyId(company.getId());
            driverEnchashment.setCompanyName(company.getAbbreviation());
            driverEnchashment.setMoney(money);
            driverEnchashment.setBank(bank);
            driverEnchashment.setCardNumber(cardNumber);
            driverEnchashment.setMasterName(masterName);
            driverEnchashment.setAfterMoney(driver.getVirtual());
            driverEnchashment.setStatus(DriverEnchashment.STATUS_WAIT);
            driverEnchashment.setType(type);
            int index = driverEnchashmentMapper.insertRecord(driverEnchashment);
            if (null != type && type.equals(DriverEnchashment.HELP_PAY)) {
                //$$$ 提现
                HelpPayRecord helpPayRecord = new HelpPayRecord();
                helpPayRecord.setChangeMoney(money.negate());
                helpPayRecord.setDriverId(driver.getId());
                helpPayRecord.setOperateType(HelpPayRecord.DESTOON_FINANCE_CASH);
                helpPayRecord.setMemo("司机" + driver.getUsername() + "[" + driver.getId() + "]申请提现" +
                    money.doubleValue() + "; 提现id[" + index + "]");

                helppayService.operateDriverMoney(helpPayRecord);

            } else {
                driver.setVirtual(driver.getVirtual().subtract(money));
                DriverPaymentsRecord driverPaymentsRecord = new DriverPaymentsRecord();
                driverPaymentsRecord.setMoney(money);
                driverPaymentsRecord.setAfterMoney(driver.getVirtual());
                driverPaymentsRecord.setDriverId(driver.getId());
                driverPaymentsRecord.setDriverRealName(driver.getRealname());
                driverPaymentsRecord.setDriverUserName(driver.getUsername());
                driverPaymentsRecord.setDriverPhone(driver.getPhone());
                driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
                driverPaymentsRecord
                    .setRecordType(DriverPaymentsRecord.CONSUMEDRECORD_TYPE_ENCHASHMENT);
                driverPaymentsRecord
                    .setRcType(DriverPaymentsRecord.DIFFERENT_NEGATIVE);
                driverPaymentsRecord
                    .setMemo("司机" + driver.getUsername() + "[" + driver.getId() + "]申请提现" +
                        money.doubleValue() + "; 提现id[" + index + "]");
                driverPaymentsRecord
                    .setOperating(DriverPaymentsRecord.OPERATING_SYS);
                driverPaymentsRecord.setHappend(new Date());
                driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }//
        driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(),
            driver.getId());

        Setting setting = settingUtils.get();
        if (driver.getStatus().equals(Driver.DRIVER_ONLINE)
            && driver.getType().equals(Driver.DRIVER_TYPR_PARTTIME)
            && setting.getLowestWorkVirtual() != 0
            && driver.getVirtual().doubleValue() < setting
            .getLowestWorkVirtual()) {

            driver.setStatus(Driver.DRIVER_OFFLINE);
            driverMapper.updateStatusByPrimaryKey(Driver.DRIVER_OFFLINE,
                driver.getId());

            DriverPowerOfflineEvent driverPowerOfflineEvent = new DriverPowerOfflineEvent(
                driver, Driver.DRIVER_ONLINE, "sys");
            applicationEventMulticaster.multicastEvent(driverPowerOfflineEvent);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(DriverEnchashment driverEnchashment, Driver driver, String result) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        boolean isHelpPay = driverEnchashment.getType() != null ? driverEnchashment.getType()
            .equals(DriverEnchashment.HELP_PAY) : false;
        String memo = null;
        if (!isHelpPay) {
            memo = "您的余额提现（" + driverEnchashment.getMoney() + "）";
        } else {
            memo = "您的可代付余额提现（" + driverEnchashment.getMoney() + "）";
        }

        if (result.equals("success")) {
            driverEnchashment.setStatus(DriverEnchashment.STATUS_SUCCESS);
            driverEnchashmentMapper.updateByPrimaryKey(driverEnchashment);
            memo += " 已通过";
        } else if (result.equals("turndown")) {
            driverEnchashment.setStatus(DriverEnchashment.STATUS_TURNDOWN);
            driverEnchashmentMapper.updateByPrimaryKey(driverEnchashment);

            if (isHelpPay) {
                HelpPayRecord helpPayRecord = new HelpPayRecord();
                helpPayRecord.setChangeMoney(driverEnchashment.getMoney());
                helpPayRecord.setDriverId(driver.getId());
                helpPayRecord.setOperateType(HelpPayRecord.AUDIT);
                helpPayRecord
                    .setMemo("管理员" + principal.getUsername() + "[" + principal.getId() + "]未通过"
                        + driver.getUsername() + "[" + driver.getId() +
                        "]的申请提现申请,返回提现可代付余额" +
                        driverEnchashment.getMoney().doubleValue() + "元");
//                helpPayRecord.setPaymentRecordId(driverPaymentsRecord.getId());
                helppayService.operateDriverMoney(helpPayRecord);

                //
            } else {
                driver.setVirtual(driver.getVirtual().add(
                    driverEnchashment.getMoney()));

                DriverPaymentsRecord driverPaymentsRecord = new DriverPaymentsRecord();
                driverPaymentsRecord.setMoney(driverEnchashment.getMoney());
                driverPaymentsRecord.setAfterMoney(driver.getVirtual());
                driverPaymentsRecord.setDriverId(driver.getId());
                driverPaymentsRecord.setDriverRealName(driver.getRealname());
                driverPaymentsRecord.setDriverUserName(driver.getUsername());
                driverPaymentsRecord.setDriverPhone(driver.getPhone());
                driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
                driverPaymentsRecord
                    .setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_ENCHASHMENT);
                driverPaymentsRecord
                    .setRcType(DriverPaymentsRecord.DIFFERENT_POSITIVE);
                if (StringUtils.isBlank(driverEnchashment.getMemo())) {
                    driverPaymentsRecord.setMemo(driverEnchashment.getMemo());
                } else {
                    driverPaymentsRecord
                        .setMemo("管理员" + principal.getUsername() + "[" + principal.getId() + "]未通过"
                            + driver.getUsername() + "[" + driver.getId() +
                            "]的申请提现申请,返回提现可代付余额" +
                            driverEnchashment.getMoney().doubleValue() + "元");
                }

                driverPaymentsRecord.setOperating(principal.getUsername());
                driverPaymentsRecord.setHappend(new Date());
                driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);

                //$$$ 审核提现

                driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(),
                    driver.getId());
            }

            memo += " 已驳回";
        }

        Notice notice = new Notice();
        notice.setCompanyId(principal.getCompanyId());
        notice.setContent(memo);
        notice.setOperating(principal.getUsername());
        noticeMapper.insertRecord(notice);

        NoticeXDriver noticeXDriver = new NoticeXDriver();
        noticeXDriver.setDriverId(driver.getId());
        noticeXDriver.setNoticeId(notice.getId());
        noticeXDriver.setHasRead(false);
        noticeXDriverMapper.insertRecord(noticeXDriver);

        List<Driver> driverList = new ArrayList<Driver>();
        driverList.add(driver);

        NoticeEvent noticeEvent = new NoticeEvent(notice, driverList);
        applicationEventMulticaster.multicastEvent(noticeEvent);
    }
}